/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

using System;
using System.Collections.Generic;

namespace FaceCat {
    /// <summary>
    /// 控件事件
    /// </summary>
    /// <param name="sender">发送者</param>
    public interface FCEventCallBack{
        /// <summary>
        /// 调用方法
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="invoke"></param>
        void callEvent(String eventName, Object sender, Object invoke);
    }

    /// <summary>
    /// 在线程中调用方法事件
    /// </summary>
    /// <param name="sender">发送者</param>
    /// <param name="args">参数</param>
    public interface FCInvokeEventCallBack {
        /// <summary>
        /// 调用Invoke事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        /// <param name="invoke"></param>
        void callInvokeEvent(String eventName, Object sender, Object args, Object invoke);
    }

    /// <summary>
    /// 键盘事件
    /// </summary>
    /// <param name="sender">发送者</param>
    /// <param name="key">按键</param>
    public interface FCKeyEventCallBack {
        /// <summary>
        /// 调用键盘事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="key"></param>
        /// <param name="invoke"></param>
        void callKeyEvent(String eventName, Object sender, char key, Object invoke);
    }
    
    /// <summary>
    /// 键盘事件
    /// </summary>
    /// <param name="sender">发送者</param>
    /// <param name="eventName">事件ID</param>
    /// <param name="key">按键</param>
    public interface FCPreviewsKeyEventCallBack {
        /// <summary>
        /// 调用事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="tEventID"></param>
        /// <param name="sender"></param>
        /// <param name="key"></param>
        /// <param name="invoke"></param>
        /// <returns></returns>
        bool callPreviewsKeyEvent(String eventName, String tEventName, Object sender, char key, Object invoke);
    }

    /// <summary>
    /// 控件触摸事件
    /// </summary>
    /// <param name="sender">发送者</param>
    /// <param name="mp">触摸位置</param>
    /// <param name="button">按钮</param>
    /// <param name="clicks">点击次数</param>
    /// <param name="delta">滚轮值</param>
    public interface FCTouchEventCallBack {
        /// <summary>
        /// 调用事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="touchInfo"></param>
        /// <param name="invoke"></param>
        void callTouchEvent(String eventName, Object sender, FCTouchInfo touchInfo, Object invoke);
    }

    /// <summary>
    /// 控件触摸事件
    /// </summary>
    /// <param name="sender">发送者</param>
    /// <param name="eventName">事件ID</param>
    /// <param name="mp">触摸位置</param>
    /// <param name="button">按钮</param>
    /// <param name="clicks">点击次数</param>
    /// <param name="delta">滚轮值</param>
    public interface FCPreviewsTouchEventCallBack {
        /// <summary>
        /// 调用事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="tEventID"></param>
        /// <param name="sender"></param>
        /// <param name="touchInfo"></param>
        /// <param name="invoke"></param>
        /// <returns></returns>
        bool callPreviewsTouchEvent(String eventName, String tEventName, Object sender, FCTouchInfo touchInfo, Object invoke);
    }

    /// <summary>
    /// 控件重绘事件
    /// </summary>
    /// <param name="sender">发送者</param>
    /// <param name="paint">绘图对象</param>
    /// <param name="clipRect">裁剪区域</param>
    public interface FCPaintEventCallBack {
        /// <summary>
        /// 调用绘图事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="paint"></param>
        /// <param name="clipRect"></param>
        /// <param name="invoke"></param>
        /// <returns></returns>
        bool callPaintEvent(String eventName, Object sender, FCPaint paint, FCRect clipRect, Object invoke);
    }

    /// <summary>
    /// 秒表事件
    /// </summary>
    /// <param name="sender">发送者</param>
    /// <param name="timerID">秒表ID</param>
    public interface FCTimerEventCallBack {
        /// <summary>
        /// 秒表事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="timerID"></param>
        /// <param name="invoke"></param>
        void callTimerEvent(String eventName, Object sender, int timerID, Object invoke);
    }

    /// <summary>
    /// 自定义集合
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ArrayList<T> : List<T> {
        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="t">数据</param>
        public void add(T t) {
            Add(t);
        }

        /// <summary>
        /// 清除数据
        /// </summary>
        public void clear() {
            Clear();
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="index">索引</param>
        /// <returns>数据</returns>
        public T get(int index) {
            return this[index];
        }

        /// <summary>
        /// 移除数据
        /// </summary>
        /// <param name="t">数据</param>
        public void remove(T t) {
            Remove(t);
        }

        /// <summary>
        /// 移除数据
        /// </summary>
        /// <param name="index">索引</param>
        public void removeAt(int index) {
            RemoveAt(index);
        }

        /// <summary>
        /// 设置数据
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="t">数据</param>
        public void set(int index, T t) {
            this[index] = t;
        }

        /// <summary>
        /// 尺寸
        /// </summary>
        /// <returns></returns>
        public int size() {
            return Count;
        }
    }

    /// <summary>
    /// 自定义哈希表
    /// </summary>
    /// <typeparam name="K"></typeparam>
    /// <typeparam name="V"></typeparam>
    public class HashMap<K, V> : Dictionary<K, V> {
        /// <summary>
        /// 清除数据
        /// </summary>
        public void clear() {
            Clear();
        }

        /// <summary>
        /// 是否包含键
        /// </summary>
        /// <param name="k">键</param>
        /// <returns>是否包含</returns>
        public bool containsKey(K k) {
            return ContainsKey(k);
        }

        /// <summary>
        /// 获取值
        /// </summary>
        /// <param name="k">键</param>
        /// <returns>值</returns>
        public V get(K k) {
            return this[k];
        }

        /// <summary>
        /// 填充数据
        /// </summary>
        /// <param name="k">键</param>
        /// <param name="v">值</param>
        public void put(K k, V v) {
            this[k] = v;
        }

        /// <summary>
        /// 移除数据
        /// </summary>
        /// <param name="k">键</param>
        public void remove(K k) {
            Remove(k);
        }

        /// <summary>
        /// 获取尺寸
        /// </summary>
        /// <returns>尺寸</returns>
        public int size() {
            return Count;
        }
    }

    /// <summary>
    /// 事件ID
    /// </summary>
    public class FCEventID {
        public static String Add = "onadd";
        public static String AutoSizeChanged = "onautosizechanged";
        public static String BackColorChanged = "onbackcolorchanged";
        public static String BackImageChanged = "onbackimagechanged";
        public static String Char = "onchar";
        public static String Click = "onclick";
        public static String Copy = "oncopy";
        public static String Cut = "oncut";
        public static String DockChanged = "ondockchanged";
        public static String DoubleClick = "ondoubleclick";
        public static String DragBegin = "ondragbegin";
        public static String DragEnd = "ondragend";
        public static String Dragging = "ondragging";
        public static String EnableChanged = "onenablechanged";
        public static String FontChanged = "onfontchanged";
        public static String TextColorChanged = "ontextcolorchanged";
        public static String GotFocus = "ongotfocus";
        public static String Invoke = "oninvoke";
        public static String KeyDown = "onkeydown";
        public static String KeyUp = "onkeyup";
        public static String Load = "onload";
        public static String LocationChanged = "onlocationchanged";
        public static String LostFocus = "onlostfocus";
        public static String MarginChanged = "onmarginchanged";
        public static String TouchDown = "ontouchdown";
        public static String TouchEnter = "ontouchenter";
        public static String TouchLeave = "ontouchleave";
        public static String TouchMove = "ontouchmove";
        public static String TouchUp = "ontouchup";
        public static String TouchWheel = "ontouchwheel";
        public static String PaddingChanged = "onpaddingchanged";
        public static String ParentChanged = "onparentchanged";
        public static String Paint = "onpaint";
        public static String PaintBorder = "onpaintborder";
        public static String Paste = "onpaste";
        public static String RegionChanged = "onregionchanged";
        public static String Remove = "onremove";
        public static String SizeChanged = "onsizechanged";
        public static String TabStop = "ontabstop";
        public static String TabStopChanged = "ontabstopchanged";
        public static String TextChanged = "ontextchanged";
        public static String Timer = "ontimer";
        public static String VisibleChanged = "onvisiblechanged";
        public static String CheckedChanged = "oncheckedchanged";
        public static String SelectedTimeChanged = "onselectedtimechanged";
        public static String GridCellClick = "ongridcellclick";
        public static String GridCellEditBegin = "ongridcelleditbegin";
        public static String GridCellEditEnd = "ongridcelleditend";
        public static String GridCellTouchDown = "ongridcelltouchdown";
        public static String GridCellTouchEnter = "ongridcelltouchenter";
        public static String GridCellTouchLeave = "ongridcelltouchleave";
        public static String GridCellTouchMove = "ongridcelltouchmove";
        public static String GridCellTouchUp = "ongridcelltouchup";
        public static String GridRowDraged = "ongridrowdraged";
        public static String GridSelectedCellsChanged = "ongridselectedcellschanged";
        public static String GridSelectedColumnsChanged = "ongridselectedcolumnschanged";
        public static String GridSelectedRowsChanged = "ongridselectedrowschanged";
        public static String MenuItemClick = "onmenuitemclick";
        public static String SelectedIndexChanged = "onselectedindexchanged";
        public static String SelectedTabPageChanged = "onselectedtabpagechanged";
        public static String Scrolled = "onscrolled";
        public static String ValueChanged = "onvaluechanged";
        public static String WindowClosed = "onwindowclosed";
        public static String WindowClosing = "onwindowclosing";
        public static String PreviewsKeyEvent = "onpreviewskeyevent";
        public static String PreviewsTouchEvent = "onpreviewstouchevent";
    }

    public class FCAtrEx{
        public FCAtrEx()
        {
        }

        ~FCAtrEx()
        {
            delete();
        }

        public void delete()
        {
            if (m_events != null)
            {
                m_events.clear();
            }
            if (m_invokes != null)
            {
                m_invokes.clear();
            }
        }

        /// <summary>
        /// 事件集合
        /// </summary>
        public HashMap<String, ArrayList<Object>> m_events;

        /// <summary>
        /// 调用者集合
        /// </summary>
        public HashMap<String, ArrayList<Object>> m_invokes;

        /// <summary>
        /// 百分比位置
        /// </summary>
        public FCPointF2 m_percentLocation = null;

        /// <summary>
        /// 百分比尺寸
        /// </summary>
        public FCSizeF2 m_percentSize = null;

        public FCAnchor m_anchor = new FCAnchor(true, true, false, false);

        public FCSize m_maximumSize = new FCSize(100000, 100000);

        public FCSize m_minimumSize;

        public FCRect m_region;

        public bool m_useRegion = false;

        public FCPadding m_padding = new FCPadding(0);

        public FCPadding m_margin = new FCPadding(0);

        public bool m_allowDrag;

        public bool m_allowPreviewsEvent = false;

        public bool m_autoEllipsis;

        public bool m_autoSize;

        public String m_backImage = "";

        public int m_cornerRadius;

        public FCCursors m_cursor = FCCursors.Arrow;

        public bool m_displayOffset = true;

        public FCDockStyle m_dock = FCDockStyle.None;

        public bool m_isDragging;

        public bool m_isWindow;

        public int m_tabIndex;

        public bool m_tabStop;

        public Object m_tag = null;

        public bool m_canFocus = true;

        public int m_borderWidth = 1;
    }

    /// <summary>
    /// 图层内置控件的基类
    /// </summary>
    public class FCView : FCAttribute {
        /// <summary>
        /// 创建控件
        /// </summary>
        public FCView() {
        }

        /// <summary>
        /// 析构函数
        /// </summary>
        ~FCView() {
            delete();
        }

        public FCAtrEx m_atrEx;

        /// <summary>
        /// 控件集合
        /// </summary>
        public ArrayList<FCView> m_views = new ArrayList<FCView>();

        /// <summary>
        /// 上次尺寸
        /// </summary>
        public FCSize m_oldSize = new FCSize();

        public FCHorizontalAlign m_align = FCHorizontalAlign.Left;

        /// <summary>
        /// 获取横向排列方式
        /// </summary>
        public virtual FCHorizontalAlign getAlign() {
            return m_align;
        }

        /// <summary>
        /// 设置横向排列方式
        /// </summary>
        public virtual void setAlign(FCHorizontalAlign align) {
            m_align = align;
        }

        /// <summary>
        /// 获取是否可以拖动位置
        /// </summary>
        public virtual bool allowDrag() {
            if (m_atrEx == null)
            {
                return false;
            }
            return m_atrEx.m_allowDrag;
        }

        /// <summary>
        /// 设置是否可以拖动位置
        /// </summary>
        public virtual void setAllowDrag(bool value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_allowDrag = value;
        }

        /// <summary>
        /// 获取是否允许预处理事件
        /// </summary>
        public virtual bool allowPreviewsEvent() {
            if (m_atrEx == null)
            {
                return false;
            }
            return m_atrEx.m_allowPreviewsEvent;
        }

        /// <summary>
        /// 设置是否允许预处理事件
        /// </summary>
        public virtual void setAllowPreviewsEvent(bool value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_allowPreviewsEvent = value;
        }

        /// <summary>
        /// 获取锚定信息
        /// </summary>
        public virtual FCAnchor getAnchor() {
            if (m_atrEx == null)
            {
                return new FCAnchor();
            }
            return m_atrEx.m_anchor;
        }

        /// <summary>
        /// 设置锚定信息
        /// </summary>
        public virtual void setAnchor(FCAnchor value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_anchor = value;
        }

        /// <summary>
        /// 获取是否在文字超出范围时在结尾显示省略号
        /// </summary>
        public virtual bool autoEllipsis() {
            if (m_atrEx == null)
            {
                return false;
            }
            return m_atrEx.m_autoEllipsis;
        }

        /// <summary>
        /// 设置是否在文字超出范围时在结尾显示省略号
        /// </summary>
        public virtual void setAutoEllipsis(bool value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_autoEllipsis = value;
        }

        /// <summary>
        /// 获取是否自动调整尺寸
        /// </summary>
        public virtual bool autoSize() {
            if (m_atrEx == null)
            {
                return false;
            }
            return m_atrEx.m_autoSize;
        }

        /// <summary>
        /// 设置是否自动调整尺寸
        /// </summary>
        public virtual void setAutoSize(bool value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            if (m_atrEx.m_autoSize != value)
            {
                m_atrEx.m_autoSize = value;
                onAutoSizeChanged();
            }
        }

        public long m_backColor = FCColor.Back;

        /// <summary>
        /// 获取背景色
        /// </summary>
        public virtual long getBackColor() {
            return m_backColor;
        }

        /// <summary>
        /// 设置背景色
        /// </summary>
        public virtual void setBackColor(long value) {
            if (m_backColor != value) {
                m_backColor = value;
                onBackColorChanged();
            }
        }

        /// <summary>
        /// 获取背景图片
        /// </summary>
        public virtual String getBackImage() {
            if (m_atrEx == null)
            {
                return "";
            }
            return m_atrEx.m_backImage;
        }

        /// <summary>
        /// 设置背景图片
        /// </summary>
        public virtual void setBackImage(String value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_backImage = value;
            onBackImageChanged();
        }

        public long m_borderColor = FCColor.Border;

        /// <summary>
        /// 获取边线的颜色
        /// </summary>
        public virtual long getBorderColor() {
            return m_borderColor;
        }

        /// <summary>
        /// 设置边线的颜色
        /// </summary>
        public virtual void setBorderColor(long value) {
            m_borderColor = value;
        }

        /// <summary>
        /// 获取边线的宽度
        /// </summary>
        public virtual int getBorderWidth()
        {
            if (m_atrEx == null)
            {
                return 1;
            }
            else
            {
                return m_atrEx.m_borderWidth;
            }
        }

        /// <summary>
        /// 设置边线的宽度
        /// </summary>
        public virtual void setBorderWidth(int value)
        {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_borderWidth = value;
        }

        /// <summary>
        /// 获取距离下侧的位置
        /// </summary>
        public int getBottom() {
            return getTop() + getHeight();
        }

        /// <summary>
        /// 获取区域
        /// </summary>
        /// <returns></returns>
        public virtual FCRect getBounds() {
            return new FCRect(getLeft(), getTop(), getRight(), getBottom());
        }

        /// <summary>
        /// 获取或设置控件的区域属性
        /// </summary>
        public virtual void setBounds(FCRect value) {
            setLocation(new FCPoint(value.left, value.top));
            int cx = value.right - value.left;
            int cy = value.bottom - value.top;
            setSize(new FCSize(cx, cy));
        }

        /// <summary>
        /// 获取或设置控件的区域属性
        /// </summary>
        public virtual void setBounds2(FCRect value)
        {
            if (m_atrEx != null)
            {
                setBounds(value);
            }
            else
            {
                m_location.x = value.left;
                m_location.y = value.top;
                m_size.cx = value.right - value.left;
                m_size.cy = value.bottom - value.top;
            }
        }


        /// <summary>
        /// 获取是否获得焦点
        /// </summary>
        public virtual bool canFocus()
        {
            if (m_atrEx == null)
            {
                return true;
            }
            return m_atrEx.m_canFocus;
        }

        /// <summary>
        /// 设置是否允许获得焦点
        /// </summary>
        public virtual void setCanFocus(bool value)
        {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_canFocus = value;
        }

        /// <summary>
        /// 获取是否被触摸捕获
        /// </summary>
        public virtual bool isCapture() {
            if (m_native != null) {
                if (m_native.getHoveredView() == this || m_native.getPushedView() == this) {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 获取圆角角度
        /// </summary>
        public virtual int getCornerRadius() {
            if (m_atrEx == null)
            {
                return 0;
            }
            return m_atrEx.m_cornerRadius;
        }

        /// <summary>
        /// 设置圆角角度
        /// </summary>
        public virtual void setCornerRadius(int cornerRadius) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_cornerRadius = cornerRadius;
        }

        /// <summary>
        /// 获取光标
        /// </summary>
        public virtual FCCursors getCursor() {
            if (m_atrEx == null)
            {
                return FCCursors.Arrow;
            }
            return m_atrEx.m_cursor;
        }

        /// <summary>
        /// 设置光标
        /// </summary>
        public virtual void setCursor(FCCursors value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_cursor = value;
        }

        /// <summary>
        /// 获取是否允许偏移显示
        /// </summary>
        /// <returns></returns>
        public virtual bool displayOffset() {
            if (m_atrEx == null)
            {
                return true;
            }
            return m_atrEx.m_displayOffset;
        }

        /// <summary>
        /// 设置是否允许偏移显示
        /// </summary>
        public virtual void setDisplayOffset(bool value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_displayOffset = value;
        }

        /// <summary>
        /// 获取虚拟显示的区域
        /// </summary>
        /// <returns></returns>
        public FCRect getDisplayRect() {
            if (m_atrEx != null && m_atrEx.m_useRegion)
            {
                return m_atrEx.m_region;
            } else {
                return new FCRect(0, 0, getWidth(), getHeight());
            }
        }

        /// <summary>
        /// 获取绑定边缘类型
        /// </summary>
        public virtual FCDockStyle getDock() {
            if (m_atrEx == null)
            {
                return FCDockStyle.None;
            }
            return m_atrEx.m_dock;
        }

        /// <summary>
        /// 设置绑定边缘类型
        /// </summary>
        public virtual void setDock(FCDockStyle value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            if (m_atrEx.m_dock != value)
            {
                m_atrEx.m_dock = value;
                onDockChanged();
            }
        }

        public bool m_enabled = true;

        /// <summary>
        /// 获取控件是否可用
        /// </summary>
        /// <returns></returns>
        public virtual bool isEnabled() {
            return m_enabled;
        }

        /// <summary>
        /// 设置控件是否可用
        /// </summary>
        /// <param name="value"></param>
        public virtual void setEnabled(bool value) {
            if (m_enabled != value) {
                m_enabled = value;
                onEnableChanged();
            }
        }

        /// <summary>
        /// 获取是否具有焦点
        /// </summary>
        public virtual bool isFocused() {
            if (m_native != null) {
                if (m_native.getFocusedView() == this) {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 设置是否具有焦点
        /// </summary>
        public virtual void setFocused(bool value) {
            if (m_native != null) {
                if (value) {
                    m_native.setFocusedView(this);
                } else {
                    if (m_native.getFocusedView() == this) {
                        m_native.setFocusedView(null);
                    }
                }
            }
        }

        public FCFont m_font = new FCFont();

        /// <summary>
        /// 获取字体
        /// </summary>
        public virtual FCFont getFont() {
            return m_font;
        }

        /// <summary>
        /// 设置字体
        /// </summary>
        public virtual void setFont(FCFont value)
        {
            m_font = value;
            onFontChanged();
        }

        /// <summary>
        /// 获取控件的高度
        /// </summary>
        public virtual int getHeight() {
            if (m_atrEx != null && m_atrEx.m_percentSize != null && m_atrEx.m_percentSize.cy != -1)
            {
                FCSize parentSize = (m_parent != null ? m_parent.getSize() : m_native.getSize());
                return (int)(parentSize.cy * m_atrEx.m_percentSize.cy);
            } else {
                return m_size.cy;
            }
        }

        /// <summary>
        /// 设置控件的高度
        /// </summary>
        public virtual void setHeight(int value) {
            if (m_atrEx != null && m_atrEx.m_percentSize != null && m_atrEx.m_percentSize.cy != -1)
            {
                return;
            } else {
                setSize(new FCSize(m_size.cx, value));
            }
        }

        public bool m_isDeleted;

        /// <summary>
        /// 获取或设置是否已被销毁
        /// </summary>
        public virtual bool isDeleted() {
            return m_isDeleted;
        }

        /// <summary>
        /// 获取或设置是否正被拖动
        /// </summary>
        /// <returns></returns>
        public virtual bool isDragging() {
            if (m_atrEx == null)
            {
                return false;
            }
            return m_atrEx.m_isDragging;
        }

        /// <summary>
        /// 获取是否为窗体
        /// </summary>
        public virtual bool isWindow() {
            if (m_atrEx == null)
            {
                return false;
            }
            return m_atrEx.m_isWindow;
        }

        /// <summary>
        /// 设置是否为窗体
        /// </summary>
        public virtual void setIsWindow(bool value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_isWindow = value;
        }

        /// <summary>
        /// 获取距离左侧的位置
        /// </summary>
        public virtual int getLeft() {
            if (m_atrEx != null && m_atrEx.m_percentLocation != null && m_atrEx.m_percentLocation.x != -1)
            {
                FCSize parentSize = (m_parent != null ? m_parent.getSize() : m_native.getSize());
                return (int)(parentSize.cx * m_atrEx.m_percentLocation.x);
            } else {
                return m_location.x;
            }
        }

        /// <summary>
        /// 设置距离左侧的位置
        /// </summary>
        public virtual void setLeft(int value) {
            if (m_atrEx != null && m_atrEx.m_percentLocation != null && m_atrEx.m_percentLocation.x != -1)
            {
                return;
            } else {
                setLocation(new FCPoint(value, m_location.y));
            }
        }

        public FCPoint m_location;

        /// <summary>
        /// 获取控件的位置
        /// </summary>
        public virtual FCPoint getLocation() {
            if (m_atrEx != null && m_atrEx.m_percentLocation != null)
            {
                FCPoint location = new FCPoint(getLeft(), getTop());
                return location;
            } else {
                return m_location;
            }
        }

        /// <summary>
        /// 设置控件的位置
        /// </summary>
        /// <param name="value"></param>
        public virtual void setLocation(FCPoint value)
        {
            if (m_location.x != value.x || m_location.y != value.y)
            {
                if (m_atrEx != null && m_atrEx.m_percentLocation != null)
                {
                    if (m_atrEx.m_percentLocation.x != -1)
                    {
                    }
                    else
                    {
                        m_location.x = value.x;
                    }
                    if (m_atrEx.m_percentLocation.y != -1)
                    {
                    }
                    else
                    {
                        m_location.y = value.y;
                    }
                }
                else
                {
                    m_location = value;
                }
                onLocationChanged();
            }
        }

        /// <summary>
        /// 获取外边距
        /// </summary>
        public virtual FCPadding getMargin() {
            if (m_atrEx == null)
            {
                return new FCPadding();
            }
            return m_atrEx.m_margin;
        }

        /// <summary>
        /// 设置外边距
        /// </summary>
        public virtual void setMargin(FCPadding value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_margin = value;
            onMarginChanged();
        }

        /// <summary>
        /// 获取控件的最大尺寸
        /// </summary>
        public virtual FCSize getMaximumSize() {
            if (m_atrEx == null)
            {
                return new FCSize(100000, 100000);
            }
            return m_atrEx.m_maximumSize;
        }

        /// <summary>
        /// 设置控件的最大尺寸
        /// </summary>
        public virtual void setMaximumSize(FCSize value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_maximumSize = value;
        }

        /// <summary>
        /// 获取控件的最小尺寸
        /// </summary>
        public virtual FCSize getMinimumSize() {
            if (m_atrEx == null)
            {
                return new FCSize(0, 0);
            }
            return m_atrEx.m_minimumSize;
        }

        /// <summary>
        /// 设置控件的最小尺寸
        /// </summary>
        public virtual void setMinimumSize(FCSize value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_minimumSize = value;
        }

        public String m_name = FCTran.getGuid();

        /// <summary>
        /// 获取控件的名称
        /// </summary>
        public virtual String getName() {
            return m_name;
        }

        /// <summary>
        /// 设置控件的名称
        /// </summary>
        public virtual void setName(String value) {
            m_name = value;
        }

        public FCNative m_native;

        /// <summary>
        /// 获取图形接口
        /// </summary>
        public virtual FCNative getNative() {
            return m_native;
        }

        /// <summary>
        /// 设置图形接口
        /// </summary>
        public virtual void setNative(FCNative value) {
            m_native = value;
            int viewsSize = m_views.size();
            for (int i = 0; i < viewsSize; i++) {
                m_views.get(i).setNative(value);
            }
            onLoad();
        }

        public float m_opacity = 1;

        /// <summary>
        /// 获取透明度
        /// </summary>
        /// <returns></returns>
        public virtual float getOpacity() {
            return m_opacity;
        }

        /// <summary>
        /// 设置透明度
        /// </summary>
        public virtual void setOpacity(float value) {
            m_opacity = value;
        }

        /// <summary>
        /// 获取内边距
        /// </summary>
        /// <returns></returns>
        public virtual FCPadding getPadding() {
            if (m_atrEx == null)
            {
                return new FCPadding();
            }
            return m_atrEx.m_padding;
        }

        /// <summary>
        /// 设置内边距
        /// </summary>
        /// <param name="value"></param>
        public virtual void setPadding(FCPadding value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_padding = value;
            onPaddingChanged();
        }

        public FCView m_parent;

        /// <summary>
        /// 获取父控件
        /// </summary>
        public virtual FCView getParent() {
            return m_parent;
        }

        /// <summary>
        /// 设置父控件
        /// </summary>
        public virtual void setParent(FCView value) {
            if (m_parent != value) {
                m_parent = value;
                onParentChanged();
            }
        }

        /// <summary>
        /// 获取裁剪矩形
        /// </summary>
        /// <returns></returns>
        public virtual FCRect getRegion() {
            if (m_atrEx == null)
            {
                return new FCRect();
            }
            return m_atrEx.m_region;
        }

        /// <summary>
        /// 设置裁剪矩形
        /// </summary>
        /// <param name="value"></param>
        public virtual void setRegion(FCRect value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_useRegion = true;
            m_atrEx.m_region = value;
            onRegionChanged();
        }

        /// <summary>
        /// 获取距离右侧的距离
        /// </summary>
        public int getRight() {
            return getLeft() + getWidth();
        }

        public FCSize m_size;

        /// <summary>
        /// 获取尺寸
        /// </summary>
        public virtual FCSize getSize() {
            if (m_atrEx != null && m_atrEx.m_percentSize != null)
            {
                FCSize size = new FCSize(getWidth(), getHeight());
                return size;
            } else {
                return m_size;
            }
        }

        /// <summary>
        /// 设置尺寸
        /// </summary>
        public virtual void setSize(FCSize value) {
            FCSize newSize = value;
            if (newSize.cx < 0)
            {
                newSize.cx = 0;
            }
            if (newSize.cy < 0)
            {
                newSize.cy = 0;
            }
            if (m_atrEx != null)
            {
                if (newSize.cx > m_atrEx.m_maximumSize.cx)
                {
                    newSize.cx = m_atrEx.m_maximumSize.cx;
                }
                if (newSize.cy > m_atrEx.m_maximumSize.cy)
                {
                    newSize.cy = m_atrEx.m_maximumSize.cy;
                }
                if (newSize.cx < m_atrEx.m_minimumSize.cx)
                {
                    newSize.cx = m_atrEx.m_minimumSize.cx;
                }
                if (newSize.cy < m_atrEx.m_minimumSize.cy)
                {
                    newSize.cy = m_atrEx.m_minimumSize.cy;
                }
            }
            if (m_size.cx != newSize.cx || m_size.cy != newSize.cy) {
                if (m_atrEx != null && m_atrEx.m_percentSize != null)
                {
                    m_oldSize = getSize();
                    if (m_atrEx.m_percentSize.cx != -1)
                    {
                    } else {
                        m_size.cx = newSize.cx;
                    }
                    if (m_atrEx.m_percentSize.cy != -1)
                    {
                    } else {
                        m_size.cy = newSize.cy;
                    }
                } else {
                    m_oldSize = m_size;
                    m_size = newSize;
                }
                onSizeChanged();
                update();
            }
        }

        /// <summary>
        /// 获取Tab键的顺序
        /// </summary>
        public virtual int getTabIndex() {
            if (m_atrEx == null)
            {
                return 0;
            }
            return m_atrEx.m_tabIndex;
        }

        /// <summary>
        /// 设置Tab键的顺序
        /// </summary>
        public virtual void setTabIndex(int value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            if (m_atrEx.m_tabIndex != value)
            {
                m_atrEx.m_tabIndex = value;
                onTabIndexChanged();
            }
        }

        /// <summary>
        /// 获取是否能用Tab键将焦点放置到该控件上
        /// </summary>
        public virtual bool isTabStop() {
            if (m_atrEx == null)
            {
                return false;
            }
            return m_atrEx.m_tabStop;
        }

        /// <summary>
        /// 设置是否能用Tab键将焦点放置到该控件上
        /// </summary>
        public virtual void setTabStop(bool value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            if (m_atrEx.m_tabStop != value)
            {
                 m_atrEx.m_tabStop = value;
                onTabStopChanged();
            }
        }

        /// <summary>
        /// 获取TAG值
        /// </summary>
        public virtual Object getTag() {
            if (m_atrEx == null)
            {
                return null;
            }
            return m_atrEx.m_tag;
        }

        /// <summary>
        /// 设置TAG值
        /// </summary>
        public virtual void setTag(Object value) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_tag = value;
        }

        public String m_text = String.Empty;

        /// <summary>
        /// 获取文字
        /// </summary>
        public virtual String getText() {
            return m_text;
        }

        /// <summary>
        /// 设置文字
        /// </summary>
        public virtual void setText(String value) {
            if (m_text != value) {
                m_text = value;
                onTextChanged();
            }
        }

        public long m_textColor = FCColor.Text;

        /// <summary>
        /// 获取前景色
        /// </summary>
        public virtual long getTextColor() {
            return m_textColor;
        }

        /// <summary>
        /// 设置前景色
        /// </summary>
        public virtual void setTextColor(long value) {
            if (m_textColor != value) {
                m_textColor = value;
                onTextColorChanged();
            }
        }

        /// <summary>
        /// 获取距离上侧的位置
        /// </summary>
        public virtual int getTop() {
            if (m_atrEx != null && m_atrEx.m_percentLocation != null && m_atrEx.m_percentLocation.y != -1)
            {
                FCSize parentSize = (m_parent != null ? m_parent.getSize() : m_native.getSize());
                return (int)(parentSize.cy * m_atrEx.m_percentLocation.y);
            } else {
                return m_location.y;
            }
        }

        /// <summary>
        /// 设置距离上侧的位置
        /// </summary>
        public virtual void setTop(int value) {
            if (m_atrEx != null && m_atrEx.m_percentLocation != null && m_atrEx.m_percentLocation.y != -1)
            {
                return;
            } else {
                setLocation(new FCPoint(m_location.x, value));
            }
        }

        public bool m_topMost = false;

        /// <summary>
        /// 获取是否置顶显示
        /// </summary>
        public virtual bool isTopMost() {
            return m_topMost;
        }

        /// <summary>
        /// 获取是否置顶显示
        /// </summary>
        public virtual void setTopMost(bool value) {
            m_topMost = value;
        }

        /// <summary>
        /// 获取触摸的实际位置
        /// </summary>
        public virtual FCPoint getTouchPoint() {
            FCPoint mp = m_native.getTouchPoint();
            return pointToView(mp);
        }

        /// <summary>
        /// 获取或设置是否设置裁剪
        /// </summary>
        public virtual bool useRegion() {
            if (m_atrEx == null)
            {
                return false;
            }
            return m_atrEx.m_useRegion;
        }

        public FCVerticalAlign m_verticalAlign = FCVerticalAlign.Top;

        /// <summary>
        /// 获取纵向排列方式
        /// </summary>
        public virtual FCVerticalAlign getVerticalAlign() {
            return m_verticalAlign;
        }

        /// <summary>
        /// 设置纵向排列方式
        /// </summary>
        public virtual void setVerticalAlign(FCVerticalAlign verticalAlign) {
            m_verticalAlign = verticalAlign;
        }

        public bool m_visible = true;

        /// <summary>
        /// 获取控件是否可见
        /// </summary>
        public virtual bool isVisible() {
            return m_visible;
        }

        /// <summary>
        /// 设置控件是否可见
        /// </summary>
        public virtual void setVisible(bool value) {
            if (m_visible != value) {
                m_visible = value;
                onVisibleChanged();
            }
        }

        /// <summary>
        /// 获取控件的宽度
        /// </summary>
        /// <returns></returns>
        public virtual int getWidth() {
            if (m_atrEx != null && m_atrEx.m_percentSize != null && m_atrEx.m_percentSize.cx != -1)
            {
                FCSize parentSize = (m_parent != null ? m_parent.getSize() : m_native.getSize());
                return (int)(parentSize.cx * m_atrEx.m_percentSize.cx);
            } else {
                return m_size.cx;
            }
        }

        /// <summary>
        /// 设置控件的宽度
        /// </summary>
        public virtual void setWidth(int value) {
            if (m_atrEx != null && m_atrEx.m_percentSize != null && m_atrEx.m_percentSize.cx != -1)
            {
                return;
            } else {
                setSize(new FCSize(value, m_size.cy));
            }
        }

        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="view">控件</param>
        public virtual void addView(FCView view) {
            view.setParent(this);
            view.setNative(m_native);
            m_views.add(view);
            view.onAdd();
        }

        /// <summary>
        /// 注册事件
        /// </summary>
        /// <param name="func">函数指针</param>
        /// <param name="eventName">事件ID</param>
        public virtual void addEvent(Object func, String eventName, Object invoke) {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            if (m_atrEx.m_events == null)
            {
                m_atrEx.m_events = new HashMap<String, ArrayList<Object>>();
            }
            if (m_atrEx.m_invokes == null)
            {
                m_atrEx.m_invokes = new HashMap<String, ArrayList<Object>>();
            }
            ArrayList<Object> eventList = null;
            if (m_atrEx.m_events.containsKey(eventName))
            {
                eventList = m_atrEx.m_events.get(eventName);
            } else {
                eventList = new ArrayList<Object>();
                m_atrEx.m_events.put(eventName, eventList);
            }
            eventList.add(func);

            ArrayList<Object> invokeList = null;
            if (m_atrEx.m_invokes.containsKey(eventName))
            {
                invokeList = m_atrEx.m_invokes.get(eventName);
            } else {
                invokeList = new ArrayList<Object>();
                m_atrEx.m_invokes.put(eventName, invokeList);
            }
            invokeList.add(invoke);
        }

        /// <summary>
        /// 在控件线程中调用方法
        /// </summary>
        /// <param name="args">参数</param>
        public virtual void beginInvoke(Object args) {
            if (m_native != null) {
                FCHost host = m_native.getHost();
                host.beginInvoke(this, args);
            }
        }

        /// <summary>
        /// 将子控件置于最前
        /// </summary>
        /// <param name="childView">子控件</param>
        public virtual void bringChildToFront(FCView childView) {
            if (m_views != null && m_views.size() > 0) {
                m_views.remove(childView);
                m_views.add(childView);
            }
        }

        /// <summary>
        /// 将控件放到最前显示
        /// </summary>
        public virtual void bringToFront() {
            if (m_native != null) {
                m_native.bringToFront(this);
            }
        }

        /// <summary>
        /// 调用事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        public virtual void callEvents(String eventName) {
            if (m_atrEx != null && m_atrEx.m_events != null && m_atrEx.m_events.containsKey(eventName))
            {
                ArrayList<Object> events = m_atrEx.m_events.get(eventName);
                ArrayList<Object> invokes = m_atrEx.m_invokes[eventName];
                int eventSize = events.size();
                for (int i = 0; i < eventSize; i++)
                {
                    FCEventCallBack func = events.get(i) as FCEventCallBack;
                    if (func != null)
                    {
                        func.callEvent(eventName, this, invokes.get(i));
                    }
                }
            }
        }

        /// <summary>
        /// 调用控件线程方法事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="args">参数</param>
        public void callInvokeEvents(String eventName, Object args) {
            if (m_atrEx != null && m_atrEx.m_events != null && m_atrEx.m_events.containsKey(eventName))
            {
                ArrayList<Object> events = m_atrEx.m_events.get(eventName);
                ArrayList<Object> invokes = m_atrEx.m_invokes[eventName];
                int eventSize = events.size();
                for (int i = 0; i < eventSize; i++)
                {
                    FCInvokeEventCallBack func = events.get(i) as FCInvokeEventCallBack;
                    if (func != null)
                    {
                        func.callInvokeEvent(eventName, this, args, invokes.get(i));
                    }
                }
            }
        }

        /// <summary>
        /// 调用键盘事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="key">按键</param>
        public virtual void callKeyEvents(String eventName, char key) {
            if (m_atrEx != null && m_atrEx.m_events != null && m_atrEx.m_events.containsKey(eventName))
            {
                ArrayList<Object> events = m_atrEx.m_events.get(eventName);
                ArrayList<Object> invokes = m_atrEx.m_invokes[eventName];
                int eventSize = events.size();
                for (int i = 0; i < eventSize; i++)
                {
                    FCKeyEventCallBack func = events.get(i) as FCKeyEventCallBack;
                    if (func != null)
                    {
                        func.callKeyEvent(eventName, this, key, invokes.get(i));
                    }
                }
            }
        }

        /// <summary>
        /// 调用重绘事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="paint">绘图对象</param>
        /// <param name="clipRect">裁剪区域</param>
        public virtual bool callPaintEvents(String eventName, FCPaint paint, FCRect clipRect) {
            if (m_atrEx != null && m_atrEx.m_events != null && m_atrEx.m_events.containsKey(eventName))
            {
                ArrayList<Object> events = m_atrEx.m_events.get(eventName);
                ArrayList<Object> invokes = m_atrEx.m_invokes[eventName];
                int eventSize = events.size();
                for (int i = 0; i < eventSize; i++)
                {
                    FCPaintEventCallBack func = events.get(i) as FCPaintEventCallBack;
                    if (func != null)
                    {
                        if (func.callPaintEvent(eventName, this, paint, clipRect, invokes.get(i)))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 预处理键盘事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="tEventID">事件ID2</param>
        /// <param name="key">键</param>
        /// <returns>是否不处理</returns>
        public virtual bool callPreviewsKeyEvent(String eventName, String tEventName, char key) {
            if (m_atrEx != null && m_atrEx.m_events != null && m_atrEx.m_events.containsKey(eventName))
            {
                ArrayList<Object> events = m_atrEx.m_events.get(eventName);
                ArrayList<Object> invokes = m_atrEx.m_invokes[eventName];
                int eventSize = events.size();
                for (int i = 0; i < eventSize; i++)
                {
                    FCPreviewsKeyEventCallBack func = events.get(i) as FCPreviewsKeyEventCallBack;
                    if (func != null)
                    {
                        if (func.callPreviewsKeyEvent(eventName, tEventName, this, key, invokes.get(i)))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 调用预触摸事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="tEventID">事件ID2</param>
        /// <param name="touchInfo">触摸信息</param>
        public virtual bool callPreviewsTouchEvents(String eventName, String tEventName, FCTouchInfo touchInfo) {
            if (m_atrEx != null && m_atrEx.m_events != null && m_atrEx.m_events.containsKey(eventName))
            {
                ArrayList<Object> events = m_atrEx.m_events.get(eventName);
                ArrayList<Object> invokes = m_atrEx.m_invokes[eventName];
                int eventSize = events.size();
                for (int i = 0; i < eventSize; i++)
                {
                    FCPreviewsTouchEventCallBack func = events.get(i) as FCPreviewsTouchEventCallBack;
                    if (func != null)
                    {
                        if (func.callPreviewsTouchEvent(eventName, tEventName, this, touchInfo, invokes.get(i)))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 调用秒表事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="timerID">秒表编号</param>
        public virtual void callTimerEvents(String eventName, int timerID) {
            if (m_atrEx != null && m_atrEx.m_events != null && m_atrEx.m_events.containsKey(eventName))
            {
                ArrayList<Object> events = m_atrEx.m_events.get(eventName);
                ArrayList<Object> invokes = m_atrEx.m_invokes[eventName];
                int eventSize = events.size();
                for (int i = 0; i < eventSize; i++)
                {
                    FCTimerEventCallBack func = events.get(i) as FCTimerEventCallBack;
                    if (func != null)
                    {
                        func.callTimerEvent(eventName, this, timerID, invokes.get(i));
                    }
                }
            }
        }

        /// <summary>
        /// 调用触摸事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void callTouchEvents(String eventName, FCTouchInfo touchInfo) {
            if (m_atrEx != null && m_atrEx.m_events != null && m_atrEx.m_events.containsKey(eventName))
            {
                ArrayList<Object> events = m_atrEx.m_events.get(eventName);
                ArrayList<Object> invokes = m_atrEx.m_invokes[eventName];
                int eventSize = events.size();
                for (int i = 0; i < eventSize; i++)
                {
                    FCTouchEventCallBack func = events.get(i) as FCTouchEventCallBack;
                    if (func != null)
                    {
                        func.callTouchEvent(eventName, this, touchInfo, invokes.get(i));
                    }
                }
            }
        }

        /// <summary>
        /// 调用方法
        /// </summary>
        /// <param name="funcName">名称</param>
        /// <param name="parameters">参数</param>
        /// <returns></returns>
        public virtual String callFunction(String funcName, String parameters)
        {
            return "";
        }

        /// <summary>
        /// 清除所有控件
        /// </summary>
        public virtual void clearViews() {
            while (m_views.size() > 0)
            {
                FCView view = m_views.get(0);
                m_views.removeAt(0);
                view.onRemove();
                view.delete();
            }
        }

        /// <summary>
        /// 是否包含控件
        /// </summary>
        /// <param name="view">控件</param>
        /// <returns>是否包含</returns>
        public virtual bool containsView(FCView view) {
            foreach (FCView subView in m_views) {
                if (subView == view) {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 是否包含坐标
        /// </summary>
        /// <param name="point">坐标</param>
        /// <returns>是否包含</returns>
        public virtual bool containsPoint(FCPoint point) {
            FCPoint cPoint = pointToView(point);
            FCSize size = getSize();
            if (cPoint.x >= 0 && cPoint.x <= size.cx && cPoint.y >= 0 && cPoint.y <= size.cy) {
                if (m_atrEx != null && m_atrEx.m_useRegion)
                {
                    if (cPoint.x >= m_atrEx.m_region.left && cPoint.x <= m_atrEx.m_region.right
                        && cPoint.y >= m_atrEx.m_region.top && cPoint.y <= m_atrEx.m_region.bottom)
                    {
                        return true;
                    }
                } else {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 销毁资源
        /// </summary>
        public virtual void delete() {
            if (!m_isDeleted) {
                if (m_atrEx != null)
                {
                    m_atrEx.delete();
                }
                clearViews();
                m_isDeleted = true;
            }
        }

        /// <summary>
        /// 设置焦点
        /// </summary>
        public virtual void focus() {
            setFocused(true);
        }

        /// <summary>
        /// 获取控件集合的拷贝
        /// </summary>
        /// <returns>控件集合</returns>
        public virtual ArrayList<FCView> getViews() {
            return m_views;
        }

        /// <summary>
        /// 获取控件类型
        /// </summary>
        /// <returns>控件类型</returns>
        public virtual String getViewType() {
            return "View";
        }

        /// <summary>
        /// 获取显示偏移坐标
        /// </summary>
        /// <returns>坐标</returns>
        public virtual FCPoint getDisplayOffset() {
            return new FCPoint(0, 0);
        }

        /// <summary>
        /// 获取事件名称列表
        /// </summary>
        /// <returns>名称列表</returns>
        public virtual ArrayList<String> getEventNames() {
            ArrayList<String> eventNames = new ArrayList<String>();
            eventNames.AddRange(new String[] { "Add", "BackColorChanged", "BackImageChanged", "Char", "Click", "Copy", "Cut", "DockChanged", "DoubleClick", "DragBegin", "DragEnd", "Dragging", "EnableChanged", "FontChanged", "GotFocus", "Invoke", "KeyDown", 
            "KeyUp", "Load", "LocationChanged", "LostFocus", "MarginChanged", "TouchDown", "TouchEnter", "TouchLeave", "TouchMove", "TouchUp", "TouchWheel", "PaddingChanged", "ParentChanged", "Paint",
            "PaintBorder", "Paste", "RegionChanged", "Remove", "SizeChanged", "TabIndexChanged", "TabStop", "TabStopChanged", "TextChanged", "TextColorChanged", "Timer", "VisibleChanged"});
            return eventNames;
        }

        public static int m_newTimerID = 0;

        /// <summary>
        /// 获取新的秒表编号
        /// </summary>
        /// <returns>新编号</returns>
        public static int getNewTimerID() {
            return m_newTimerID++;
        }

        /// <summary>
        /// 获取要绘图时的背景色
        /// </summary>
        /// <returns>背景色</returns>
        public virtual long getPaintingBackColor() {
            if (m_backColor != FCColor.None && FCColor.DisabledBack != FCColor.None) {
                if (!isPaintEnabled(this)) {
                    return FCColor.DisabledBack;
                }
            }
            return m_backColor;
        }

        /// <summary>
        /// 获取要绘制的背景图片
        /// </summary>
        /// <returns>背景图片</returns>
        public virtual String getPaintingBackImage() {
            return getBackImage();
        }

        /// <summary>
        /// 获取要绘制的边线颜色
        /// </summary>
        /// <returns>边线颜色</returns>
        public virtual long getPaintingBorderColor() {
            return m_borderColor;
        }

        /// <summary>
        /// 获取要绘制的前景色
        /// </summary>
        /// <returns>前景色</returns>
        public virtual long getPaintingTextColor() {
            if (m_textColor != FCColor.Text && FCColor.DisabledText != FCColor.None) {
                if (!isPaintEnabled(this)) {
                    return FCColor.DisabledText;
                }
            }
            return m_textColor;
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="name">属性名称</param>
        /// <returns>属性值</returns>
        public virtual String getAttribute(String name) {
            String value = "", type = "";
            getAttribute(name, ref value, ref type);
            return value;
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="name">属性名称</param>
        /// <param name="value">返回属性值</param>
        /// <param name="type">返回属性类型</param>
        public virtual void getAttribute(String name, ref String value, ref String type) {
            int len = name.Length;
            switch (len) {
                case 1:
                    {
                        if (name == "x")
                        {
                            type = "float";
                            if (m_atrEx != null && m_atrEx.m_percentLocation != null && m_atrEx.m_percentLocation.x != -1)
                            {
                                value = "%" + FCTran.floatToStr(100 * m_atrEx.m_percentLocation.x);
                            }
                            else
                            {
                                value = FCTran.intToStr(getLeft());
                            }
                        }
                        else if (name == "y")
                        {
                            type = "float";
                            if (m_atrEx != null && m_atrEx.m_percentLocation != null && m_atrEx.m_percentLocation.y != -1)
                            {
                                value = "%" + FCTran.floatToStr(100 * m_atrEx.m_percentLocation.y);
                            }
                            else
                            {
                                value = FCTran.intToStr(getTop());
                            }
                        }
                        break;
                    }
                case 2: {
                        if (name == "id") {
                            type = "text";
                            value = getName();
                        }
                        break;
                    }
                case 3: {
                        if (name == "top") {
                            type = "float";
                            if (m_atrEx != null && m_atrEx.m_percentLocation != null && m_atrEx.m_percentLocation.y != -1)
                            {
                                value = "%" + FCTran.floatToStr(100 * m_atrEx.m_percentLocation.y);
                            } else {
                                value = FCTran.intToStr(getTop());
                            }
                        }
                        break;
                    }
                case 4: {
                        if (name == "dock") {
                            type = "enum:FCDockStyle";
                            value = FCTran.dockToStr(getDock());
                        } else if (name == "font") {
                            type = "font";
                            value = FCTran.fontToStr(getFont());
                        } else if (name == "left") {
                            type = "float";
                            if (m_atrEx != null && m_atrEx.m_percentLocation != null && m_atrEx.m_percentLocation.x != -1)
                            {
                                value = "%" + FCTran.floatToStr(100 * m_atrEx.m_percentLocation.x);
                            } else {
                                value = FCTran.intToStr(getLeft());
                            }
                        } else if (name == "name") {
                            type = "text";
                            value = getName();
                        } else if (name == "size") {
                            type = "size";
                            if (m_atrEx != null && m_atrEx.m_percentSize != null)
                            {
                                String pWidth = "", pHeight = "", pType = "";
                                getAttribute("width", ref pWidth, ref pType);
                                getAttribute("height", ref pHeight, ref pType);
                                value = pWidth + "," + pHeight;
                            } else {
                                value = FCTran.sizeToStr(getSize());
                            }
                        } else if (name == "text") {
                            type = "text";
                            value = getText();
                        }
                        break;
                    }
                case 5: {
                        if (name == "align") {
                            type = "enum:FCHorizontalAlign";
                            value = FCTran.horizontalAlignToStr(getAlign());
                        } else if (name == "value") {
                            type = "text";
                            value = getText();
                        } else if (name == "width") {
                            type = "float";
                            if (m_atrEx != null && m_atrEx.m_percentSize != null && m_atrEx.m_percentSize.cx != -1)
                            {
                                value = "%" + FCTran.floatToStr(100 * m_atrEx.m_percentSize.cx);
                            } else {
                                value = FCTran.intToStr(getWidth());
                            }
                        }
                        break;
                    }
                case 6: {
                        if (name == "anchor") {
                            type = "anchor";
                            value = FCTran.anchorToStr(getAnchor());
                        } else if (name == "bounds") {
                            type = "rect";
                            value = FCTran.rectToStr(getBounds());
                        } else if (name == "cursor") {
                            type = "enum:FCCursors";
                            value = FCTran.cursorToStr(getCursor());
                        } else if (name == "height") {
                            type = "float";
                            if (m_atrEx != null && m_atrEx.m_percentSize != null && m_atrEx.m_percentSize.cy != -1)
                            {
                                value = "%" + FCTran.floatToStr(100 * m_atrEx.m_percentSize.cy);
                            } else {
                                value = FCTran.intToStr(getHeight());
                            }
                        } else if (name == "margin") {
                            type = "margin";
                            value = FCTran.paddingToStr(getMargin());
                        } else if (name == "region") {
                            type = "rect";
                            value = FCTran.rectToStr(getRegion());
                        }
                        break;
                    }
                case 7: {
                        if (name == "enabled") {
                            type = "bool";
                            value = FCTran.boolToStr(isEnabled());
                        } else if (name == "focused") {
                            type = "bool";
                            value = FCTran.boolToStr(isFocused());
                        } else if (name == "opacity") {
                            type = "float";
                            value = FCTran.floatToStr(getOpacity());
                        } else if (name == "padding") {
                            type = "padding";
                            value = FCTran.paddingToStr(getPadding());
                        } else if (name == "tabstop") {
                            type = "bool";
                            value = FCTran.boolToStr(isTabStop());
                        } else if (name == "topmost") {
                            type = "bool";
                            value = FCTran.boolToStr(isTopMost());
                        } else if (name == "visible") {
                            type = "bool";
                            value = FCTran.boolToStr(isVisible());
                        }
                        break;
                    }
                case 8: {
                        if (name == "autosize") {
                            type = "bool";
                            value = FCTran.boolToStr(autoSize());
                        }else if (name == "iswindow") {
                            type = "bool";
                            value = FCTran.boolToStr(isWindow());
                        } else if (name == "location") {
                            type = "point";
                            if (m_atrEx != null && m_atrEx.m_percentLocation != null)
                            {
                                String pLeft = "", pTop = "", pType = "";
                                getAttribute("left", ref pLeft, ref pType);
                                getAttribute("top", ref pTop, ref pType);
                                value = pLeft + "," + pTop;
                            } else {
                                value = FCTran.pointToStr(getLocation());
                            }
                        } else if (name == "tabindex") {
                            type = "int";
                            value = FCTran.intToStr(getTabIndex());
                        }
                        else if (name == "canfocus")
                        {
                            type = "bool";
                            value = FCTran.boolToStr(canFocus());
                        }
                        break;
                    }
                case 9: {
                        if (name == "allowdrag") {
                            type = "bool";
                            value = FCTran.boolToStr(allowDrag());
                        } else if (name == "backcolor") {
                            type = "color";
                            value = FCTran.colorToStr(getBackColor());
                        } else if (name == "backimage") {
                            type = "text";
                            value = getBackImage();
                        } else if (name == "textcolor") {
                            type = "color";
                            value = FCTran.colorToStr(getTextColor());
                        }
                        break;
                    }
                default: {
                        if (name == "allowpreviewsevent") {
                            type = "bool";
                            value = FCTran.boolToStr(allowPreviewsEvent());
                        } else if (name == "autoellipsis") {
                            type = "bool";
                            value = FCTran.boolToStr(autoEllipsis());
                        } else if (name == "bordercolor") {
                            type = "color";
                            value = FCTran.colorToStr(getBorderColor());
                        }else if (name == "cornerradius") {
                            type = "int";
                            value = FCTran.intToStr(getCornerRadius());
                        } else if (name == "displayoffset") {
                            type = "bool";
                            value = FCTran.boolToStr(displayOffset());
                        } else if (name == "maximumsize") {
                            type = "size";
                            value = FCTran.sizeToStr(getMaximumSize());
                        } else if (name == "minimumsize") {
                            type = "size";
                            value = FCTran.sizeToStr(getMinimumSize());
                        }else if (name == "vertical-align") {
                            type = "enum:FCVerticalAlign";
                            value = FCTran.verticalAlignToStr(getVerticalAlign());
                        }
                        else if (name == "borderwidth")
                        {
                            type = "int";
                            value = FCTran.intToStr(getBorderWidth());
                        }
                        break;
                    }
            }
        }

        /// <summary>
        /// 获取属性名称列表
        /// </summary>
        /// <returns></returns>
        public virtual ArrayList<String> getAttributeNames() {
            ArrayList<String> attributeNames = new ArrayList<String>();
            attributeNames.AddRange(new String[] { "Align", "AllowDrag", "AllowPreviewsEvent", "Anchor", "AutoEllipsis", "AutoSize", "BackColor", "BackImage", "BorderColor", "Bounds",  
            "BorderWidth", "CanFocus", "CornerRadius", "Cursor", "DisplayOffset", "Dock", "Enabled", "Focused", "Font", "Height", "IsWindow", "Left",
            "Location", "Margin", "MaximumSize", "MinimumSize", "Name", "Opacity", "Padding", "Region", "Size", "TabIndex", "TabStop", "Text", "TextColor", 
            "Top", "TopMost", "Value", "Vertical-Align", "Visible", "Width", "X", "Y"});
            return attributeNames;
        }

        /// <summary>
        /// 判断是否包含子控件
        /// </summary>
        /// <returns>是否包含子控件</returns>
        public bool hasChildren() {
            return m_views.size() > 0;
        }

        /// <summary>
        /// 隐藏控件
        /// </summary>
        public virtual void hide() {
            setVisible(false);
        }

        /// <summary>
        /// 插入控件
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="view">控件</param>
        public virtual void insertView(int index, FCView view) {   
            view.setParent(this);
            view.setNative(m_native);
            m_views.Insert(index, view);
            view.onAdd();
        }

        /// <summary>
        /// 启动绘制
        /// </summary>
        public virtual void invalidate() {
            if (m_native != null) {
                if (isPaintVisible(this))
                {
                    m_native.invalidate(this);
                }
            }
        }

        /// <summary>
        /// 在控件线程中调用方法
        /// </summary>
        /// <param name="args">参数</param>
        public virtual void invoke(Object args) {
            if (m_native != null) {
                FCHost host = m_native.getHost();
                host.invoke(this, args);
            }
        }

        /// <summary>
        /// 判断是否绘制可用状态
        /// </summary>
        /// <param name="view">控件</param>
        /// <returns>是否绘制可用状态</returns>
        public bool isPaintEnabled(FCView view) {
            if (view.isEnabled()) {
                FCView parent = view.getParent();
                if (parent != null) {
                    return isPaintEnabled(parent);
                } else {
                    return true;
                }
            } else {
                return false;
            }
        }

        /// <summary>
        /// 判断是否绘图时可见
        /// </summary>
        /// <param name="view">控件</param>
        /// <returns>是否可见</returns>
        public bool isPaintVisible(FCView view) {
            if (view.isVisible()) {
                FCView parent = view.getParent();
                if (parent != null) {
                    return isPaintVisible(parent);
                } else {
                    return true;
                }
            } else {
                return false;
            }
        }

        /// <summary>
        /// 添加控件时触发
        /// </summary>
        public virtual void onAdd() {
            callEvents("onadd");
        }

        /// <summary>
        /// 自动设置尺寸属性改变时触发
        /// </summary>
        public virtual void onAutoSizeChanged() {
            callEvents("onautosizechanged");
        }

        /// <summary>
        /// 背景色改变时触发
        /// </summary>
        public virtual void onBackColorChanged() {
            callEvents("onbackcolorchanged");
        }

        /// <summary>
        /// 背景图片改变时触发
        /// </summary>
        public virtual void onBackImageChanged() {
            callEvents("onbackimagechanged");
        }

        /// <summary>
        /// 字符输入时触发
        /// </summary>
        /// <param name="ch">字符</param>
        public virtual void onChar(char ch) {
            callKeyEvents("onchar", ch);
        }

        /// <summary>
        /// 触摸点击时触发
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onClick(FCTouchInfo touchInfo) {
            callTouchEvents("onclick", touchInfo);
        }

        /// <summary>
        /// 复制时触发
        /// </summary>
        public virtual void onCopy() {
            callEvents("oncopy");
        }

        /// <summary>
        /// 剪切时触发
        /// </summary>
        public virtual void onCut() {
            callEvents("oncut");
        }

        /// <summary>
        /// 悬停改变时触发
        /// </summary>
        public virtual void onDockChanged() {
            callEvents("ondockchanged");
        }

        /// <summary>
        /// 触摸双击时触发
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onDoubleClick(FCTouchInfo touchInfo) {
            callTouchEvents("ondoubleclick", touchInfo);
        }

        /// <summary>
        /// 拖动开始时触发
        /// </summary>
        /// <returns>是否拖动</returns>
        public virtual bool onDragBegin() {
            callEvents("ondragbegin");
            return true;
        }

        /// <summary>
        /// 拖动结束时触发
        /// </summary>
        public virtual void onDragEnd() {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_isDragging = false;
            callEvents("ondragend");
        }

        /// <summary>
        /// 正在拖动时触发
        /// </summary>
        public virtual void onDragging() {
            if (m_atrEx == null)
            {
                m_atrEx = new FCAtrEx();
            }
            m_atrEx.m_isDragging = true;
            callEvents("ondragging");
        }

        /// <summary>
        /// 文件拖入方法
        /// </summary>
        /// <param name="files"></param>
        public virtual void onDragInFiles(ArrayList<String> files)
        {
        }

        /// <summary>
        /// 拖动准备方法
        /// </summary>
        /// <param name="startOffset">可以拖动的偏移坐标量</param>
        public virtual void onDragReady(ref FCPoint startOffset) {
            startOffset.x = 5;
            startOffset.y = 5;
        }

        /// <summary>
        /// 可用改变时触发
        /// </summary>
        public virtual void onEnableChanged() {
            callEvents("onenablechanged");
        }

        /// <summary>
        /// 字体改变时触发
        /// </summary>
        public virtual void onFontChanged() {
            callEvents("onfontchanged");
        }

        /// <summary>
        /// 获得焦点时触发
        /// </summary>
        public virtual void onGotFocus() {
            callEvents("ongotfocus");
        }

        /// <summary>
        /// 在控件线程中调用方法
        /// </summary>
        /// <param name="args">参数</param>
        public virtual void onInvoke(Object args) {
            callInvokeEvents("oninvoke", args);
        }

        /// <summary>
        /// 控件加载时触发
        /// </summary>
        public virtual void onLoad() {
            callEvents("onload");
        }

        /// <summary>
        /// 位置改变时触发
        /// </summary>
        public virtual void onLocationChanged() {
            callEvents("onlocationchanged");
        }

        /// <summary>
        /// 丢失焦点时触发
        /// </summary>
        public virtual void onLostFocus() {
            callEvents("onlostfocus");
        }

        /// <summary>
        /// 键盘按下时触发
        /// </summary>
        /// <param name="key">按键</param>
        public virtual void onKeyDown(char key) {
            callKeyEvents("onkeydown", key);
            FCHost host = getNative().getHost();
            if (host.isKeyPress(0x11)) {
                //复制
                if (key == 67) {
                    onCopy();
                }
                    //粘贴
                else if (key == 86) {
                    onPaste();
                }
                    //剪切
                else if (key == 88) {
                    onCut();
                }
            }
        }

        /// <summary>
        /// 键盘弹起起触发
        /// </summary>
        /// <param name="key">按键</param>
        public virtual void onKeyUp(char key) {
            callKeyEvents("onkeyup", key);
        }

        /// <summary>
        /// 外边距改变时触发
        /// </summary>
        public virtual void onMarginChanged() {
            callEvents("onmarginchanged");
        }

        /// <summary>
        /// 内边距改变时触发
        /// </summary>
        public virtual void onPaddingChanged() {
            callEvents("onpaddingchanged");
        }

        /// <summary>
        /// 重绘时触发
        /// </summary>
        /// <param name="paint">绘图对象</param>
        /// <param name="clipRect">裁剪区域</param>
        public virtual void onPaint(FCPaint paint, FCRect clipRect) {
            onPaintBackground(paint, clipRect);
            onPaintForeground(paint, clipRect);
            callPaintEvents("onpaint", paint, clipRect);
        }

        /// <summary>
        /// 重绘背景时触发
        /// </summary>
        /// <param name="paint">绘图对象</param>
        /// <param name="clipRect">裁剪区域</param>
        public virtual void onPaintBackground(FCPaint paint, FCRect clipRect) {
            FCRect rect = new FCRect(0, 0, getWidth(), getHeight());
            //绘制背景色
            paint.fillRoundRect(getPaintingBackColor(), rect, getCornerRadius());
            //绘制背景图
            String bkImage = getPaintingBackImage();
            if (bkImage != null && bkImage.Length > 0) {
                paint.drawImage(bkImage, rect);
            }
        }

        /// <summary>
        /// 重绘边线时触发
        /// </summary>
        /// <param name="paint">绘图对象</param>
        /// <param name="clipRect">裁剪区域</param>
        public virtual void onPaintBorder(FCPaint paint, FCRect clipRect) {
            FCRect borderRect = new FCRect(0, 0, getWidth(), getHeight());
            //绘制边线
            paint.drawRoundRect(getPaintingBorderColor(), getBorderWidth(), 0, borderRect, getCornerRadius());
            callPaintEvents("onpaintborder", paint, clipRect);
        }

        /// <summary>
        /// 重绘前景方法
        /// </summary>
        /// <param name="paint">绘图对象</param>
        /// <param name="clipRect">裁剪区域</param>
        public virtual void onPaintForeground(FCPaint paint, FCRect clipRect) {
        }

        /// <summary>
        /// 父容器改变方法
        /// </summary>
        public virtual void onParentChanged() {
            callEvents("onparentchanged");
        }

        /// <summary>
        /// 复制时触发
        /// </summary>
        public virtual void onPaste() {
            callEvents("onpaste");
        }

        /// <summary>
        /// 预绘图方法
        /// </summary>
        /// <param name="paint">绘图对象</param>
        /// <param name="clipRect">裁剪区域</param>
        public virtual bool onPrePaint(FCPaint paint, FCRect clipRect) {
            return callPaintEvents("onprepaint", paint, clipRect);
 
        }

        /// <summary>
        /// 键盘预处理事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="key">按键</param>
        /// <returns>状态</returns>
        public virtual bool onPreviewsKeyEvent(String eventName, char key) {
            return callPreviewsKeyEvent("onpreviewskeyevent", eventName, key);
        }

        /// <summary>
        /// 预处理触摸事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="touchInfo">触摸信息</param>
        /// <returns>状态</returns>
        public virtual bool onPreviewsTouchEvent(String eventName, FCTouchInfo touchInfo) {
            return callPreviewsTouchEvents("onpreviewstouchevent", eventName, touchInfo);
        }

        /// <summary>
        /// 移除控件时触发
        /// </summary>
        public virtual void onRemove() {
            callEvents("onremove");
        }

        /// <summary>
        /// 裁剪区域改变时触发
        /// </summary>
        public virtual void onRegionChanged() {
            callEvents("onregionchanged");
        }

        /// <summary>
        /// 缩放
        /// </summary>
        /// <param name="scaleFactorX">横向比例</param>
        /// <param name="scaleFactorY">纵向比例</param>
        public virtual void onScaling(double scaleFactorX, double scaleFactorY) {
            m_location = new FCPoint((int)(m_location.x * scaleFactorX), (int)(m_location.y * scaleFactorY));
            m_size = new FCSize((int)(m_size.cx * scaleFactorX), (int)(m_size.cy * scaleFactorY));
            m_font.m_fontSize = (float)(m_font.m_fontSize * (scaleFactorX + scaleFactorY) / 2);
            if (m_atrEx != null)
            {
                m_atrEx.m_maximumSize = new FCSize((int)(m_atrEx.m_maximumSize.cx * scaleFactorX), (int)(m_atrEx.m_maximumSize.cy * scaleFactorY));
                m_atrEx.m_minimumSize = new FCSize((int)(m_atrEx.m_minimumSize.cx * scaleFactorX), (int)(m_atrEx.m_minimumSize.cy * scaleFactorY));
            }
            int viewSize = m_views.size();
            for (int i = 0; i < viewSize; i++) {
                m_views.get(i).onScaling(scaleFactorX, scaleFactorY);
            }
        }

        /// <summary>
        /// 尺寸改变时触发
        /// </summary>
        public virtual void onSizeChanged() {
            callEvents("onsizechanged");
        }

        /// <summary>
        /// TAB索引改变时触发
        /// </summary>
        public virtual void onTabIndexChanged() {
            callEvents("ontabindexchanged");
        }

        /// <summary>
        /// 被使用TAB切换时触发
        /// </summary>
        public virtual void onTabStop() {
            callEvents("ontabstop");
        }

        /// <summary>
        /// 是否用TAB切换改变方法
        /// </summary>
        public virtual void onTabStopChanged() {
            callEvents("ontabstopchanged");
        }

        /// <summary>
        /// 文本改变时触发
        /// </summary>
        public virtual void onTextChanged() {
            callEvents("ontextchanged");
        }

        /// <summary>
        /// 文字颜色改变时触发
        /// </summary>
        public virtual void onTextColorChanged() {
            callEvents("ontextcolorchanged");
        }

        /// <summary>
        /// 触摸按下方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onTouchDown(FCTouchInfo touchInfo) {
            callTouchEvents("ontouchdown", touchInfo);
        }

        /// <summary>
        /// 触摸进入方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onTouchEnter(FCTouchInfo touchInfo) {
            callTouchEvents("ontouchenter", touchInfo);
            if (autoEllipsis()) {
                if (m_text != null && m_text.Length > 0) {
                    m_native.getHost().showToolTip(m_text, m_native.getTouchPoint());
                }
            }
        }

        /// <summary>
        /// 触摸离开方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onTouchLeave(FCTouchInfo touchInfo) {
            callTouchEvents("ontouchleave", touchInfo);
        }

        /// <summary>
        /// 触摸移动调用方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onTouchMove(FCTouchInfo touchInfo) {
            callTouchEvents("ontouchmove", touchInfo);
        }

        /// <summary>
        /// 触摸抬起方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onTouchUp(FCTouchInfo touchInfo) {
            callTouchEvents("ontouchup", touchInfo);
        }

        /// <summary>
        /// 触摸滚动方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onTouchWheel(FCTouchInfo touchInfo) {
            callTouchEvents("ontouchwheel", touchInfo);
        }

        /// <summary>
        /// 秒表回调方法
        /// </summary>
        /// <param name="timerID">编号</param>
        public virtual void onTimer(int timerID) {
            callTimerEvents("ontimer", timerID);
        }

        /// <summary>
        /// 可见状态改变时触发
        /// </summary>
        public virtual void onVisibleChanged() {
            callEvents("onvisiblechanged");
        }

        /// <summary>
        /// 获取相对于控件的相对坐标
        /// </summary>
        /// <param name="point">坐标</param>
        /// <returns>相对坐标</returns>
        public FCPoint pointToView(FCPoint point) {
            if (m_native != null) {
                int clientX = m_native.clientX(this);
                int clientY = m_native.clientY(this);
                return new FCPoint(point.x - clientX, point.y - clientY);
            } else {
                return point;
            }
        }

        /// <summary>
        /// 获取控件的绝对坐标
        /// </summary>
        /// <param name="point">坐标</param>
        /// <returns>绝对坐标</returns>
        public FCPoint pointToNative(FCPoint point) {
            if (m_native != null) {
                int clientX = m_native.clientX(this);
                int clientY = m_native.clientY(this);
                return new FCPoint(point.x + clientX, point.y + clientY);
            } else {
                return point;
            }
        }

        /// <summary>
        /// 移除控件
        /// </summary>
        /// <param name="view">控件</param>
        public virtual void removeView(FCView view) {
            if (m_native != null) {
                m_native.clearViewState(view);
            }
            m_views.remove(view);
            view.onRemove();
            view.setParent(null);
        }

        /// <summary>
        /// 取消注册事件
        /// </summary>
        /// <param name="func">函数指针</param>
        /// <param name="eventName">事件ID</param>
        public virtual void removeEvent(Object func, String eventName) {
            if (m_atrEx != null && m_atrEx.m_events != null && m_atrEx.m_events.containsKey(eventName))
            {
                ArrayList<Object> funcs = m_atrEx.m_events.get(eventName);
                int funcsSize = funcs.size();
                for (int i = 0; i < funcsSize; i++) {
                    if (funcs.get(i) == func)
                    {
                        m_atrEx.m_events.get(eventName).removeAt(i);
                        m_atrEx.m_invokes.get(eventName).removeAt(i);
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 将控件置于最后
        /// </summary>
        /// <param name="childView">子控件</param>
        public virtual void sendChildToBack(FCView childView) {
            if (m_views != null && m_views.size() > 0) {
                m_views.remove(childView);
                m_views.Insert(0, childView);
            }
        }


        /// <summary>
        /// 将控件放到最下面显示
        /// </summary>
        public virtual void sendToBack() {
            if (m_native != null) {
                m_native.sendToBack(this);
            }
        }

        /// <summary>
        /// 设置属性
        /// </summary>
        /// <param name="name">属性名称</param>
        /// <param name="value">属性值</param>
        public virtual void setAttribute(String name, String value) {
            int len = name.Length;
            switch (len)
            {
                case 1:
                    {
                        if (name == "x")
                        {
                            if (value.IndexOf("%") != -1)
                            {
                                if (m_atrEx == null)
                                {
                                    m_atrEx = new FCAtrEx();
                                }
                                float percentValue = FCTran.strToFloat(value.Replace("%", "")) / 100;
                                if (m_atrEx.m_percentLocation == null)
                                {
                                    m_atrEx.m_percentLocation = new FCPointF2();
                                    m_atrEx.m_percentLocation.y = -1;
                                }
                                m_atrEx.m_percentLocation.x = percentValue;
                            }
                            else
                            {
                                if (m_atrEx != null && m_atrEx.m_percentLocation != null)
                                {
                                    m_atrEx.m_percentLocation.x = -1;
                                }
                                setLeft(FCTran.strToInt(value));
                            }
                        }
                        else if (name == "y")
                        {
                            if (value.IndexOf("%") != -1)
                            {
                                if (m_atrEx == null)
                                {
                                    m_atrEx = new FCAtrEx();
                                }
                                float percentValue = FCTran.strToFloat(value.Replace("%", "")) / 100;
                                if (m_atrEx.m_percentLocation == null)
                                {
                                    m_atrEx.m_percentLocation = new FCPointF2();
                                    m_atrEx.m_percentLocation.x = -1;
                                }
                                m_atrEx.m_percentLocation.y = percentValue;
                            }
                            else
                            {
                                if (m_atrEx != null && m_atrEx.m_percentLocation != null)
                                {
                                    m_atrEx.m_percentLocation.y = -1;
                                }
                                setTop(FCTran.strToInt(value));
                            }

                        }
                        break;
                    }
                case 2:
                    {
                        if (name == "id")
                        {
                            setName(value);
                        }
                        break;
                    }
                case 3:
                    {
                        if (name == "top")
                        {
                            if (value.IndexOf("%") != -1)
                            {
                                if (m_atrEx == null)
                                {
                                    m_atrEx = new FCAtrEx();
                                }
                                float percentValue = FCTran.strToFloat(value.Replace("%", "")) / 100;
                                if (m_atrEx.m_percentLocation == null)
                                {
                                    m_atrEx.m_percentLocation = new FCPointF2();
                                    m_atrEx.m_percentLocation.x = -1;
                                }
                                m_atrEx.m_percentLocation.y = percentValue;
                            }
                            else
                            {
                                if (m_atrEx != null && m_atrEx.m_percentLocation != null)
                                {
                                    m_atrEx.m_percentLocation.y = -1;
                                }
                                setTop(FCTran.strToInt(value));
                            }

                        }
                        break;
                    }
                case 4:
                    {
                        switch (name)
                        {
                            case "dock":
                                {
                                    setDock(FCTran.strToDock(value));
                                    break;
                                }
                            case "font":
                                {
                                    setFont(FCTran.strToFont(value));
                                    break;
                                }
                            case "left":
                                {
                                    if (value.IndexOf("%") != -1)
                                    {
                                        if (m_atrEx == null)
                                        {
                                            m_atrEx = new FCAtrEx();
                                        }
                                        float percentValue = FCTran.strToFloat(value.Replace("%", "")) / 100;
                                        if (m_atrEx.m_percentLocation == null)
                                        {
                                            m_atrEx.m_percentLocation = new FCPointF2();
                                            m_atrEx.m_percentLocation.y = -1;
                                        }
                                        m_atrEx.m_percentLocation.x = percentValue;
                                    }
                                    else
                                    {
                                        if (m_atrEx != null && m_atrEx.m_percentLocation != null)
                                        {
                                            m_atrEx.m_percentLocation.x = -1;
                                        }
                                        setLeft(FCTran.strToInt(value));
                                    }
                                    break;
                                }
                            case "name":
                                {
                                    setName(value);
                                    break;
                                }
                            case "size":
                                {
                                    if (value.IndexOf("%") == -1)
                                    {
                                        setSize(FCTran.strToSize(value));
                                    }
                                    else
                                    {
                                        String[] strs = value.Split(',');
                                        setAttribute("width", strs[0]);
                                        setAttribute("height", strs[1]);
                                    }
                                    break;
                                }
                            case "text":
                                {
                                    setText(value);
                                    break;
                                }
                        }
                        break;
                    }
                case 5:
                    {
                        switch (name)
                        {
                            case "align":
                                {
                                    setAlign(FCTran.strToHorizontalAlign(value));
                                    break;
                                }
                            case "value":
                                {
                                    setText(value);
                                    break;
                                }
                            case "width":
                                {
                                    if (value.IndexOf("%") != -1)
                                    {
                                        if (m_atrEx == null)
                                        {
                                            m_atrEx = new FCAtrEx();
                                        }
                                        float percentValue = FCTran.strToFloat(value.Replace("%", "")) / 100;
                                        if (m_atrEx.m_percentSize == null)
                                        {
                                            m_atrEx.m_percentSize = new FCSizeF2();
                                            m_atrEx.m_percentSize.cy = -1;
                                        }
                                        m_atrEx.m_percentSize.cx = percentValue;
                                    }
                                    else
                                    {
                                        if (m_atrEx != null && m_atrEx.m_percentSize != null)
                                        {
                                            m_atrEx.m_percentSize.cx = -1;
                                        }
                                        setWidth(FCTran.strToInt(value));
                                    }
                                    break;
                                }
                        }
                        break;
                    }
                case 6:
                    {
                        switch (name)
                        {
                            case "anchor":
                                {
                                    setAnchor(FCTran.strToAnchor(value));
                                    break;
                                }
                            case "bounds":
                                {
                                    setBounds(FCTran.strToRect(value));
                                    break;
                                }
                            case "cursor":
                                {
                                    setCursor(FCTran.strToCursor(value));
                                    break;
                                }
                            case "height":
                                {
                                    if (value.IndexOf("%") != -1)
                                    {
                                        if (m_atrEx == null)
                                        {
                                            m_atrEx = new FCAtrEx();
                                        }
                                        float percentValue = FCTran.strToFloat(value.Replace("%", "")) / 100;
                                        if (m_atrEx.m_percentSize == null)
                                        {
                                            m_atrEx.m_percentSize = new FCSizeF2();
                                            m_atrEx.m_percentSize.cx = -1;
                                        }
                                        m_atrEx.m_percentSize.cy = percentValue;
                                    }
                                    else
                                    {
                                        if (m_atrEx != null && m_atrEx.m_percentSize != null)
                                        {
                                            m_atrEx.m_percentSize.cy = -1;
                                        }
                                        setHeight(FCTran.strToInt(value));
                                    }
                                    break;
                                }
                            case "margin":
                                {
                                    setMargin(FCTran.strToPadding(value));
                                    break;
                                }
                            case "region":
                                {
                                    setRegion(FCTran.strToRect(value));
                                    break;
                                }
                        }
                        break;
                    }
                case 7:
                    {
                        switch (name)
                        {
                            case "enabled":
                                {
                                    setEnabled(FCTran.strToBool(value));
                                    break;
                                }
                            case "focused":
                                {
                                    setFocused(FCTran.strToBool(value));
                                    break;
                                }
                            case "opacity":
                                {
                                    setOpacity(FCTran.strToFloat(value));
                                    break;
                                }
                            case "padding":
                                {
                                    setPadding(FCTran.strToPadding(value));
                                    break;
                                }
                            case "tabstop":
                                {
                                    setTabStop(FCTran.strToBool(value));
                                    break;
                                }
                            case "topmost":
                                {
                                    setTopMost(FCTran.strToBool(value));
                                    break;
                                }
                            case "visible":
                                {
                                    setVisible(FCTran.strToBool(value));
                                    break;
                                }
                        }
                        break;
                    }
                case 8:
                    {
                        switch (name)
                        {
                            case "autosize":
                                {
                                    setAutoSize(FCTran.strToBool(value));
                                    break;
                                }
                            case "iswindow":
                                {
                                    setIsWindow(FCTran.strToBool(value));
                                    break;
                                }
                            case "location":
                                {
                                    if (value.IndexOf("%") == -1)
                                    {
                                        setLocation(FCTran.strToPoint(value));
                                    }
                                    else
                                    {
                                        String[] strs = value.Split(',');
                                        setAttribute("left", strs[0]);
                                        setAttribute("top", strs[1]);
                                    }
                                    break;
                                }
                            case "tabindex":
                                {
                                    setTabIndex(FCTran.strToInt(value));
                                    break;
                                }
                            case "canfocus":
                                {
                                    setCanFocus(FCTran.strToBool(value));
                                    break;
                                }
                        }
                        break;
                    }
                case 9:
                    {
                        switch (name)
                        {
                            case "allowdrag":
                                {
                                    setAllowDrag(FCTran.strToBool(value));
                                    break;
                                }
                            case "backcolor":
                                {
                                    setBackColor(FCTran.strToColor(value));
                                    break;
                                }
                            case "backimage":
                                {
                                    setBackImage(value);
                                    break;
                                }
                            case "textcolor":
                                {
                                    setTextColor(FCTran.strToColor(value));
                                    break;
                                }
                        }
                        break;
                    }
                default:
                    {
                        switch (name)
                        {
                            case "allowpreviewsevent":
                                {
                                    setAllowPreviewsEvent(FCTran.strToBool(value));
                                    break;
                                }
                            case "autoellipsis":
                                {
                                    setAutoEllipsis(FCTran.strToBool(value));
                                    break;
                                }
                            case "bordercolor":
                                {
                                    setBorderColor(FCTran.strToColor(value));
                                    break;
                                }
                            case "cornerradius":
                                {
                                    setCornerRadius(FCTran.strToInt(value));
                                    break;
                                }
                            case "displayoffset":
                                {
                                    setDisplayOffset(FCTran.strToBool(value));
                                    break;
                                }
                            case "maximumsize":
                                {
                                    setMaximumSize(FCTran.strToSize(value));
                                    break;
                                }
                            case "minimumsize":
                                {
                                    setMinimumSize(FCTran.strToSize(value));
                                    break;
                                }
                            case "vertical-align":
                                {
                                    setVerticalAlign(FCTran.strToVerticalAlign(value));
                                    break;
                                }
                            case "borderwidth":
                                {
                                    setBorderWidth(FCTran.strToInt(value));
                                    break;
                                }
                        }
                        break;
                    }
            }
        }

        /// <summary>
        /// 显示控件
        /// </summary>
        public virtual void show() {
            setVisible(true);
        }

        /// <summary>
        /// 开始秒表
        /// </summary>
        /// <param name="timerID">编号</param>
        /// <param name="interval">间隔</param>
        public virtual void startTimer(int timerID, int interval) {
            if (m_native != null) {
                m_native.startTimer(this, timerID, interval);
            }
        }

        /// <summary>
        /// 停止秒表
        /// </summary>
        /// <param name="timerID">编号</param>
        public virtual void stopTimer(int timerID) {
            if (m_native != null) {
                m_native.stopTimer(timerID);
            }
        }

        /// <summary>
        /// 更新界面
        /// </summary>
        public virtual void update() {
            if (m_native != null && !m_native.m_lockUpdate) {
                m_native.setAlign(m_views);
                if (m_oldSize.cx > 0 && m_oldSize.cy > 0) {
                    m_native.setAnchor(m_views, m_oldSize);
                }
                m_native.setDock(m_views);
                m_oldSize = getSize();
                int viewsSize = m_views.size();
                for (int i = 0; i < viewsSize; i++) {
                    m_views.get(i).update();
                }
            }
        }
    }
}
